# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-07-15 23:11
# File     : alpha_vantage_adapter.py
# Project  : dynamic-portfolio-optimizer
# Desc     :
# src/data/adapters/alpha_vantage_adapter.py
from alpha_vantage.timeseries import TimeSeries
from alpha_vantage.fundamentaldata import FundamentalData
from typing import Dict, List, Any
import pandas as pd
from datetime import datetime
from .base_adapter import BaseDataAdapter, RateLimitDecorator


class AlphaVantageAdapter(BaseDataAdapter):
    """Alpha Vantage数据适配器"""

    def __init__(self, config):
        super().__init__(config)
        self.ts = TimeSeries(key=config.api_key, output_format='pandas')
        self.fd = FundamentalData(key=config.api_key, output_format='pandas')

    @RateLimitDecorator(calls=5, period=60)  # 每分钟5次请求
    def get_stock_data(self, symbol: str, start_date: datetime,
                       end_date: datetime, interval: str = '1d') -> pd.DataFrame:
        """获取股票数据"""
        try:
            # 根据间隔选择合适的函数
            if interval == '1d':
                data, meta_data = self.ts.get_daily_adjusted(symbol=symbol, outputsize='full')
            elif interval == '1h':
                data, meta_data = self.ts.get_intraday(symbol=symbol, interval='60min', outputsize='full')
            elif interval == '5m':
                data, meta_data = self.ts.get_intraday(symbol=symbol, interval='5min', outputsize='full')
            else:
                data, meta_data = self.ts.get_daily_adjusted(symbol=symbol, outputsize='full')

            if data.empty:
                self.logger.warning(f"Alpha Vantage: 未获取到{symbol}的数据")
                return pd.DataFrame()

            # 过滤日期范围
            data = data.loc[start_date:end_date]

            # 重命名列
            column_mapping = {
                '1. open': 'open',
                '2. high': 'high',
                '3. low': 'low',
                '4. close': 'close',
                '5. adjusted close': 'adj_close',
                '6. volume': 'volume'
            }

            data = data.rename(columns=column_mapping)
            data['source'] = 'alpha_vantage'
            data['symbol'] = symbol

            return self.standardize_data(data)

        except Exception as e:
            self.logger.error(f"Alpha Vantage获取股票数据失败: {e}")
            return pd.DataFrame()

    def get_options_data(self, symbol: str, expiration_date: datetime) -> pd.DataFrame:
        """获取期权数据 (Alpha Vantage不支持期权数据)"""
        self.logger.info("Alpha Vantage不支持期权数据")
        return pd.DataFrame()

    @RateLimitDecorator(calls=5, period=60)
    def get_fundamentals(self, symbol: str) -> Dict[str, Any]:
        """获取基本面数据"""
        try:
            # 获取公司概况
            overview, _ = self.fd.get_company_overview(symbol)

            if overview.empty:
                self.logger.warning(f"Alpha Vantage: 未获取到{symbol}的基本面数据")
                return {}

            # 获取收益报告
            try:
                earnings, _ = self.fd.get_earnings(symbol)
                quarterly_earnings = earnings.get('quarterlyEarnings', [])
                latest_eps = quarterly_earnings[0].get('reportedEPS', 0) if quarterly_earnings else 0
            except:
                latest_eps = 0

            fundamentals = {
                'symbol': symbol,
                'company_name': overview.get('Name', ''),
                'sector': overview.get('Sector', ''),
                'industry': overview.get('Industry', ''),
                'market_cap': float(overview.get('MarketCapitalization', 0)),
                'pe_ratio': float(overview.get('PERatio', 0)),
                'pb_ratio': float(overview.get('PriceToBookRatio', 0)),
                'dividend_yield': float(overview.get('DividendYield', 0)),
                'beta': float(overview.get('Beta', 0)),
                'eps': float(latest_eps),
                'revenue': float(overview.get('RevenueTTM', 0)),
                'gross_margin': float(overview.get('GrossProfitTTM', 0)),
                'profit_margin': float(overview.get('ProfitMargin', 0)),
                'roe': float(overview.get('ReturnOnEquityTTM', 0)),
                'debt_to_equity': float(overview.get('DebtToEquityRatio', 0)),
                'source': 'alpha_vantage'
            }

            return fundamentals

        except Exception as e:
            self.logger.error(f"Alpha Vantage获取基本面数据失败: {e}")
            return {}

    def get_news(self, symbol: str, limit: int = 10) -> List[Dict[str, Any]]:
        """获取新闻数据"""
        try:
            # Alpha Vantage有新闻API，但需要单独处理
            url = f"https://www.alphavantage.co/query"
            params = {
                'function': 'NEWS_SENTIMENT',
                'tickers': symbol,
                'apikey': self.config.api_key,
                'limit': limit
            }

            response = self.session.get(url, params=params)
            data = response.json()

            processed_news = []
            if 'feed' in data:
                for item in data['feed'][:limit]:
                    processed_news.append({
                        'symbol': symbol,
                        'title': item.get('title', ''),
                        'summary': item.get('summary', ''),
                        'url': item.get('url', ''),
                        'published_at': datetime.strptime(item.get('time_published', ''), '%Y%m%dT%H%M%S'),
                        'source': 'alpha_vantage',
                        'sentiment': item.get('overall_sentiment_score', 0)
                    })

            return processed_news

        except Exception as e:
            self.logger.error(f"Alpha Vantage获取新闻数据失败: {e}")
            return []
